/**
 * Copyright (C) 2021 - 2031 O-Cubes Co., Ltd.
 */

/****************************************************************
 *  @file    irq.c
 *  @brief   IRQ func
 *  @version v1.0
 *  @date    03. Apr. 2023
 ****************************************************************/

#include <stdint.h>

#include "irq.h"
#include "common.h"
#include "bits.h"

extern void Default_Handler(void);

/* FIX ME */
#define INT_CONTEXT_ENTER()
#define INT_CONTEXT_EXIT()

uint32_t      g_irq_nested_level;
irq_handle_t  g_irq_table[CLINT_IRQ_NUM + CLIC_IRQ_NUM];

/**
 * Configure irq attribute.
 */
void irq_cfg_attr(uint32_t irq_num, enum irq_tri_attr attr)
{
	uint8_t val = CLIC->CLICINT[irq_num].ATTR;

	val = SET_REG_BITS(val, INT_TRI_ATTR_POS, INT_TRI_ATTR_LEN, attr);
	val = SET_REG_BITS(val, INT_SHV_ATTR_POS, INT_SHV_ATTR_LEN, IRQ_SHV_ATTR_ENABLE);

	CLIC->CLICINT[irq_num].ATTR = val;
}

/**
 * register irq handler.
 */
void irq_attach(uint32_t irq_num, irq_handler handler, void *priv)
{
	g_irq_table[irq_num].handler = handler;
	g_irq_table[irq_num].priv    = priv;
}

/**
 * unregister irq handler.
 */
void irq_detach(uint32_t irq_num)
{
	g_irq_table[irq_num].handler = (void *)Default_Handler;
	g_irq_table[irq_num].priv    = NULL;
}

/**
 * gets whether in irq context
 */
bool is_in_irq_context(void)
{
	return ((g_irq_nested_level > 0U) ? true : false);
}

/**
 * dispatching irq handlers
 */
__ATTR_RAM_CODE __weak void do_irq(void)
{
	uint32_t irqn;

	g_irq_nested_level++;

	INT_CONTEXT_ENTER();

	irqn = irq_get_irq_num();

	if (g_irq_table[irqn].handler) {
		g_irq_table[irqn].handler(g_irq_table[irqn].priv);
	}

	INT_CONTEXT_EXIT();

	g_irq_nested_level--;
}

